今天來練習撰寫 keyboard interaction (輸入 type、切換 tab) 的寫法。
使用情境
延伸昨日畫面上包含四個 Element:兩個按鈕,一個輸入框,一個顯示數字的 heading。
import { useState } from "react"
export default function Counter(){
const [ counter, setCounter ] = useState(0);
return(
<>
<h1>{counter}</h1>
<div>
<label htmlFor="type">Type Number</label>
<input
type="number"
name="Type"
id="type"
value={counter}
onChange={(e) => setCounter(Number(e.target.value))}
/>
</div>
<div>
<button onClick={() => setCounter(pre => pre+1)}>+ 1</button>
<button onClick={() => setCounter(pre => pre-1)}>- 1</button>
</div>
</>
)
}
先確認四個元素都有出現在畫面上:
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import Counter from "./counter";
describe("Counter", () => {
// (1) 檢查四個元素是否有正確顯示在畫面上,與初始值
test("Render correctly!", () => {
render(<Counter />);
const counterEl = screen.getByRole("heading", {
level: 1
});
expect(counterEl).toHaveTextContent("0"); // 記得要輸入的是字串型別
const addBtnEl = screen.getByRole("button", {
name: "Add 1"
});
expect(addBtnEl).toBeInTheDocument();
const minusBtnEl = screen.getByRole("button", {
name: "Minus 1"
});
expect(minusBtnEl).toBeInTheDocument();
const inputNumberBtnEl = screen.getByRole("spinbutton");
expect(inputNumberBtnEl).toBeInTheDocument();
});
});
測試結果:
PASS src/components/counter/counter.test.tsx
撰寫測試:
describe("Counter", () => {
// (3) 模擬使用者鍵盤輸入數字
test("Change Number when typing", async () => {
render(<Counter />);
const inputNumberBtnEl = screen.getByRole("spinbutton");
await userEvent.type(inputNumberBtnEl, "23");
expect(inputNumberBtnEl).toHaveValue(23); // 確認輸入框符合鍵盤輸入內容
const counterEl = screen.getByRole("heading", {
level: 1
});
expect(counterEl).toHaveTextContent("23"); // 確認畫面顯示符合鍵盤輸入內容
})
});
測試結果:
PASS src/components/counter/counter.test.tsx
預期使用者鍵盤輸入 Tab,畫面上的輸入框 與 按鈕會依序 onFocus 的狀態。
撰寫測試:Tab 依序 輸入框 -> 加一按鈕 -> 減一按鈕。
describe("Counter", () => {
// (4) 模擬使用者鍵盤 Tab,每個元素依序 onFocus
test("Focus Element by order", async () => {
render(<Counter />);
const inputNumberBtnEl = screen.getByRole("spinbutton");
const addBtnEl = screen.getByRole("button", {
name: "Add 1"
});
const minusBtnEl = screen.getByRole("button", {
name: "Minus 1"
});
await userEvent.tab();
expect(inputNumberBtnEl).toHaveFocus();
await userEvent.tab();
expect(addBtnEl).toHaveFocus();
await userEvent.tab();
expect(minusBtnEl).toHaveFocus();
});
});
測試結果:
PASS src/components/counter/counter.test.tsx